package controller

import (
	"context"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/util/gconv"
	"seawolf-admin-go/internal/model/entity"
	"seawolf-admin-go/internal/request/BaseReq"
	"seawolf-admin-go/internal/routers"
	"seawolf-admin-go/internal/service/AdminService"
	"seawolf-admin-go/utility/db"
	"seawolf-admin-go/utility/response"
	"strings"
)

type cAdmin struct {
	*BaseController
}

func NewAdminController(group *ghttp.RouterGroup, defaultVersion string) {
	// 初始化内部变量
	inputReq := &BaseReq.I{}
	c := &cAdmin{&BaseController{Req: inputReq}}
	c.New(group, defaultVersion)
}

func (c *cAdmin) New(group *ghttp.RouterGroup, defaultVersion string) {
	ctx := context.Background()
	var leftJoin []*BaseReq.QueryOpLeftJoin
	dbPrefixTmp, _ := g.Cfg().Get(ctx, "database.prefix", "")
	dbPrefix := dbPrefixTmp.String()
	leftJoin = append(leftJoin, &BaseReq.QueryOpLeftJoin{
		TableInfo: dbPrefix + "sys_department sd",
		Condition: "a.dept_id = sd.id",
	})
	// 配置表名
	c.Req = &BaseReq.I{
		TableName:          "admin",
		InfoIgnoreProperty: "password,password_salt,delete_at",
		SoftDeleteField:    "delete_at",
		ListQueryOp: &BaseReq.QueryOp{
			IsCache: 600,
			OtherWhere: func(r *ghttp.Request) g.Map {
				return g.Map{
					"is_org": 0,
				}
			},
		},
		InfoQueryOp: &BaseReq.QueryOp{
			OtherWhere: func(r *ghttp.Request) g.Map {
				return g.Map{
					"is_org": 0,
				}
			},
		},
		PageQueryOp: &BaseReq.QueryOp{
			SelectFields: []string{
				"a.id",
				"a.account",
				"a.dept_id",
				"a.realname",
				"a.nickname",
				"a.avatar",
				"a.phone",
				"a.remark",
				"a.status",
				"a.create_at",
				"sd.name AS departmentName",
			},
			KeyWordLikeFields: []string{
				"a.account",
				"a.realname",
				"a.nickname",
			},
			AsName:   "a",
			LeftJoin: leftJoin,
			OtherWhere: func(r *ghttp.Request) g.Map {
				departmentIds := r.Get("departmentIds")
				data := g.Map{
					"a.account != ?": "admin",
					"a.is_org":       0,
				}
				if departmentIds != nil {
					data["a.dept_id IN (?)"] = departmentIds.Ints()
				}
				roleIds := r.Get("roleIds")
				if roleIds != nil {
					data["a.id IN (SELECT admin_id FROM "+dbPrefix+"admin_role WHERE role_id IN (?))"] = roleIds.Ints()
				}
				return data
			},
		},
		PageAfterFn: func(r *ghttp.Request, result g.List) (g.List, error) {
			if len(result) == 0 {
				return result, nil
			}

			// 获取角色名
			var roleList []*entity.SysRole
			// 把角色表的数据转换成map
			err := db.GetUnSafaTable(ctx, "sys_role").Where("delete_at", 0).
				Fields("id,name").Scan(&roleList)
			if err != nil {
				return nil, err
			}
			if roleList == nil {
				return result, nil
			}
			if len(roleList) == 0 {
				return result, nil
			}
			adminIds := make([]int, 0)
			for _, v := range result {
				adminIds = append(adminIds, gconv.Int(v["id"]))
			}
			// 获取用户角色
			var adminRoleList []*entity.AdminRole
			err = db.GetUnSafaTable(ctx, "admin_role").Where("admin_id IN (?)", adminIds).
				Fields("admin_id,role_id").Scan(&adminRoleList)
			if err != nil {
				return nil, err
			}
			if adminRoleList == nil {
				return result, nil
			}
			if len(adminRoleList) == 0 {
				return result, nil
			}
			// 把用户角色转换成map
			adminRoleMap := make(map[int64][]int64)
			for _, v := range adminRoleList {
				adminRoleMap[v.AdminId] = append(adminRoleMap[v.AdminId], v.RoleId)
			}
			roleMap := make(map[int64]string)
			for _, v := range roleList {
				roleMap[v.Id] = v.Name
			}
			PhotoPreFixTmp, err := g.Cfg().Get(ctx, "upload.PhotoPreFix", "")
			for _, v := range result {
				tmpId := gconv.Int64(v["id"])
				rms := adminRoleMap[tmpId]
				if rms == nil {
					continue
				}
				roleNames := []string{}
				for _, rm := range rms {
					roleNames = append(roleNames, roleMap[rm])
				}
				v["roleName"] = strings.Join(roleNames, ",")
				v["avatar_profix"] = PhotoPreFixTmp.String()
			}
			return result, nil
		},
		InfoAfterFn: func(r *ghttp.Request, result map[string]interface{}) (map[string]interface{}, error) {
			if result == nil {
				return result, nil
			}
			// 取部门名称
			dName, err := db.GetUnSafaTable(ctx, "sys_department").Where("id", result["dept_id"]).Fields("name").Value()
			if err != nil {
				return nil, err
			}
			result["departmentName"] = dName.String()
			// 取角色
			roleIds, err := db.GetUnSafaTable(ctx, "admin_role").Where("admin_id", result["id"]).Fields("role_id").Array()
			if err != nil {
				return nil, err
			}
			if roleIds != nil {
				result["roleIdList"] = gconv.SliceInt(roleIds)
			}
			PhotoPreFixTmp, err := g.Cfg().Get(ctx, "upload.PhotoPreFix", "")
			result["avatar_profix"] = PhotoPreFixTmp.String()
			return result, nil
		},
		AddInsertData: func(r *ghttp.Request) g.Map {
			return g.Map{
				"is_org": 0,
			}
		},
		UpdateInsertData: func(r *ghttp.Request) g.Map {
			return g.Map{
				"is_org": 0,
			}
		},
	}
	// 处理初始化方法和结束方法中间件
	group.Middleware(func(r *ghttp.Request) {
		c.Init(r)
		r.Middleware.Next()
		c.Shut(r)
	})
	// 注册基础路由
	RegBase(group, c, nil)

	// 获取当前登录用户的权限菜单
	group.GET("/permmenu", func(r *ghttp.Request) {
		routers.MethodCallWithVersionStrategy(r, map[string]interface{}{
			"1.0.0": c.permmenu,
		}, defaultVersion, routers.DemoteStrategy)
	})
	// 重置密码
	group.POST("/resetPass", func(r *ghttp.Request) {
		routers.MethodCallWithVersionStrategy(r, map[string]interface{}{
			"1.0.0": c.ResetPass,
		}, defaultVersion, routers.DemoteStrategy)
	})
	// 我的信息，账号信息
	group.GET("/person", func(r *ghttp.Request) {
		routers.MethodCallWithVersionStrategy(r, map[string]interface{}{
			"1.0.0": c.Person,
		}, defaultVersion, routers.DemoteStrategy)
	})
	// 修改我的信息，账号信息
	group.POST("/personUpdate", func(r *ghttp.Request) {
		routers.MethodCallWithVersionStrategy(r, map[string]interface{}{
			"1.0.0": c.PersonUpdate,
		}, defaultVersion, routers.DemoteStrategy)
	})
	// 修改密码
	group.POST("/changePass", func(r *ghttp.Request) {
		routers.MethodCallWithVersionStrategy(r, map[string]interface{}{
			"1.0.0": c.ChangePass,
		}, defaultVersion, routers.DemoteStrategy)
	})
	// 退出登录
	group.POST("/logout", func(r *ghttp.Request) {
		routers.MethodCallWithVersionStrategy(r, map[string]interface{}{
			"1.0.0": c.Logout,
		}, defaultVersion, routers.DemoteStrategy)
	})
}

func (c *cAdmin) permmenu(r *ghttp.Request) (err error) {
	ctx := r.GetCtx()
	c.Req.AdminId = r.GetCtxVar("admin_id", 0).Int()
	r.Response.WriteJsonExit(AdminService.Permmenu(ctx, c.Req))
	return
}

func (c *cAdmin) Add(r *ghttp.Request) *response.JsonResponse {
	return AdminService.Add(r, c.Req)
}

func (c *cAdmin) Update(r *ghttp.Request) *response.JsonResponse {
	c.Req.Id = r.Get("id", "").String()
	return AdminService.Update(r, c.Req)
}

func (c *cAdmin) ResetPass(r *ghttp.Request) *response.JsonResponse {
	if err := c.checkIds(r); err != nil {
		return response.FailByRequestMessage(nil, err.Error())
	}
	c.Req.AdminId = r.GetCtxVar("admin_id", 0).Int()
	return AdminService.ResetPass(r, c.Req)
}

func (c *cAdmin) Person(r *ghttp.Request) *response.JsonResponse {
	c.Req.AdminId = r.GetCtxVar("admin_id", 0).Int()
	return AdminService.Person(r.GetCtx(), c.Req)
}

func (c *cAdmin) ChangePass(r *ghttp.Request) *response.JsonResponse {
	c.Req.AdminId = r.GetCtxVar("admin_id", 0).Int()
	return AdminService.ChangePass(r, c.Req)
}

func (c *cAdmin) PersonUpdate(r *ghttp.Request) *response.JsonResponse {
	c.Req.AdminId = r.GetCtxVar("admin_id", 0).Int()
	return AdminService.PersonUpdate(r, c.Req)
}

func (c *cAdmin) Logout(r *ghttp.Request) *response.JsonResponse {
	c.Req.AdminId = r.GetCtxVar("admin_id", 0).Int()
	return AdminService.Logout(r, c.Req)
}
